# coding:utf-8
#########################
#   Author : Lion yu    #
#   Date : 2023/07/28   #
#   Id : SM2772         #
#########################
import time
import click
from inputimeout import inputimeout, TimeoutOccurred
from handle import *
from tbUtils.getResp import *
from tbUtils.DataIntoDB import *
from tbUtils.statistics import statisticsData
from tbUtils.statistics2week import statisticsData2Week
from distributed import MyZK as MZK
from Notice.ddNotice import DDnotices

ProjectIdListBase = [i for i, j in ProjectConfig.items()]

class Chief(object):
    # 数据初始化
    # 项目自定义字段 与 项目Bug等级sfcId 数据必须优先写入
    # 生成task文件
    # 生成bug文件
    # 生成bug快照文件
    # 生成bug月统计文件
    # 生成bug周统计文件
    # 数据写入
    def __init__(self) -> None:
        pass
    
    @click.command()
    @click.option('--projectid', default="", help='input your ProjectId.')
    def chief(projectid):
        input_text = "是否需要执行部门成员数据更新：空(直接回车)或非1 : 不更新， 1 : 更新 \n"
        input_timeout = 5
        try:
            is_membersWrite = inputimeout(prompt=f"{input_text}请在{input_timeout}秒内输入,超时后默认 不更新\n", timeout=input_timeout)
        except TimeoutOccurred as t:
            is_membersWrite = ""
        if isinstance(projectid, str) and len(projectid) == 0:
            projectidList = ProjectIdListBase
        elif isinstance(projectid, str) and len(projectid) > 0:
            projectidList_ext:list = projectid.strip().split(",")
            set1 = set(projectidList_ext)
            set2 = set(ProjectIdListBase)
            setIntersection = set1&set2
            if len(setIntersection) == len(projectidList_ext):
                projectidList = projectid.strip().split(",")
            else:
                Log.error("输入项目Id有误, projectId不存在")
                return
        else:
            Log.error("输入项目Id有误！")
            return
        
        zkClient = MZK()
        # 先检查锁释放 不记录锁，发现存在未释放直接return
        for projectId in projectidList:
            # 如果没有获取到锁，则加锁，否则退出
            projectId_isLocked = zkClient.getLock(projectId)
            if projectId_isLocked is False:
                Log.error(f"项目:{projectId} 该锁未释放。程序退出")
                zkClient.stop()
                return
        zkClient.stop()
        
        if is_membersWrite == 1:
            OrgDepartments_DataWrite()
            DepartmentMembers_DataWrite()
            
        Handle.db_delete(table='project')
        Log.info(f"项目表 开始写入")
        ProjectQuery_DataWrite()
        
        Tables = [
            'bugs_ext', 'bugs_level_info_ext', 'bugs_snapshot_ext', 'bugs_statistics_ext', 'task_ext', 
            'task_type_info_ext', 'bugSfcId_ext', 'projectId_columns_ext', 'bugs_statistics2week'
                    ]
        for projectId in projectidList:
            # 数据初始化(写入文件)
            dataInit(projectId)
            write_startTime = time.time()
            for table in Tables:
                Handle.db_delete(table=table, where=f"projectId = '{projectId}'")
            # 数据写入
            dataWrite(projectId=projectId)
            write_finishTime = time.time()
            Log.info(f"{projectId} 运行结束 耗时 {round(int(write_finishTime-write_startTime)/60, 2)} 分钟")
            
        # 钉钉通知
        ProjectIdListBaseExt = [i for i, j in ProjectConfig.items()]
        projectidList.sort()
        ProjectIdListBaseExt.sort()
        projectLinkInfo = {i:j['NoticeConf'] for i, j in ProjectConfig.items() if len(j['NoticeConf']) > 0}
        isAppoint = False
        if projectidList != ProjectIdListBaseExt:
            isAppoint = True
            projectIdList = [i for i in projectidList if i in list(projectLinkInfo.keys())]
            projectLinkInfo = {i:projectLinkInfo[i] for i in projectIdList}
        
        projectLinkMaps = [{"title": list(j.keys())[0], "actionURL" : list(j.values())[0]} for i, j in projectLinkInfo.items()]
        projectNames = " \n\n ".join([f"** {list(j.keys())[0]} **" for i, j in projectLinkInfo.items()])
        
        # 钉钉通知初始化
        DingTalkNotice = DDnotices()
        try:
            DingTalkNotice.send_message(msg=projectNames, btnsInfo=projectLinkMaps, isAppoint=isAppoint)
            Log.info("钉钉消息发送成功")
        except Exception as e:
            Log.error("钉钉消息发送失败")
        Log.info("All processing programs have been executed this time\n")
        return
        
            

def dataWrite(projectId):
    Log.info('task_ext 开始写入')
    ProjectTaskQuery_DataWrite(projectId, 'task_ext')
    Log.info('task_type_info_ext 开始写入')
    ScenarioFieldConfigSearch_DataWrite(projectId, 'task_type_info_ext')
    Log.info('bugs_ext 开始写入')
    ProjectBugQuery_DataWrite(projectId, 'bugs_ext')
    Log.info('bugs_snapshot_ext 开始写入')
    AllTaskActivity_DataWrite(projectId, 'bugs_snapshot_ext')
    Log.info('statistics 开始写入')
    statisticsData_DataWrite(projectId)
    Log.info('statistics2Week 开始写入')
    statistics2Week_DataWrite(projectId)
    
def dataInit(projectId):
    Log.info(f"projectId:{projectId} data init is startd")
    init_startTime = time.time()
    Handle.db_delete(table="projectId_columns_ext", where=f"projectId = '{projectId}'")
    Handle.db_delete(table="bugSfcId_ext", where=f"projectId = '{projectId}'")
    BugSfcId_DataWrite(projectId, table_name='bugSfcId_ext')
    Log.info(f"projectId : {projectId} 项目自定义字段 与 项目Bug等级sfcId 数据 写入完成")
    
    # 生成task文件
    SimpleResp_ProjectTaskQuery(projectId)
    Log.info(f"projectId : {projectId} Task文件 生成完成")
    # 生成待处理的bug文件
    Bugs_BaseData(projectId)
    # 记录 项目Bug 与 tfsId、reopenID 映射 写入
    ProjectColumns_DataWrite(projectId)
    # 生成bug文件
    SimpleResp_ProjectBugQuery(projectId)
    Log.info(f"projectId : {projectId} Bug文件 生成完成")
    # 生成bug快照文件
    AllTaskActivity(projectId)
    Log.info(f"projectId : {projectId} Bug快照文件 生成完成")
    # 生成bug月统计文件
    statisticsData(projectId)
    Log.info(f"projectId : {projectId} Bug月统计文件 生成完成")
    # 生成bug周统计文件
    statisticsData2Week(projectId)
    Log.info(f"projectId : {projectId} Bug周统计文件 生成完成")
    init_finishTime = time.time()
    Log.info(f"projectId : {projectId} init datas is finished, used {round(init_finishTime-init_startTime, 2)} seconds")


if __name__ == "__main__":
    ch = Chief()
    ch.chief()